import { ethers } from "ethers";
import store from "../store";
import { c2cContract, usdtContract ,btcContract,lpFee} from "./config";
import { C2CAbi } from "./abi/c2cAbi";
import { qutorAbi } from "@/utils/abi/qutorAbi.js";
import eth from "./eth";
import { getDate } from "@/utils/index.js";
import AESUtils from "@/utils/AES.js";
import { IPFS_PUBLIC_URL } from "@/api/User.js";
import IndexDBCache from "@/hooks/sql/useOrder.js";
import { showToast } from "vant";
import userEth from "./userEth";
const orderDB = new IndexDBCache();
const pageSize = 100;
const sumStart = (end) => {
  return end + 1 - pageSize > 0 ? end + 1 - pageSize : 0;
};
const pageNumAdd = (params) => {
  params.page = params.page + 1;
  return params;
};
const pageNum = (params) => {
  params.end = params.start - 1;
  params.start = sumStart(params.end);
  return params;
};
let provider, Contract, signer, ContractWithSinger;
try {
  provider = new ethers.providers.Web3Provider(window.ethereum);
  Contract = new ethers.Contract(
    c2cContract,
    C2CAbi.abi,
    provider
  );
  signer = provider.getSigner();
  ContractWithSinger = Contract.connect(signer);
} catch (error) {}
const c2cEth = {
  Contract,
  ContractWithSinger,
  async getPrice(account) {
    let price = 0
    try {
      // btc价格
      price = parseFloat(Number(ethers.utils.formatUnits(await Contract.callStatic.getPrice(),usdtContract[3])).toFixed(4));
    } catch (err) {
    } finally {
      store.commit("changeTokenPrice", price);
      return price;
    }
  },
  
  async getOrderPlatformFee(id) {
    let price = 0
    try {
      // btc价格
       let data  = await Contract.orderFeeList(id)
       let fee1 = Number(ethers.utils.formatUnits(data.platformFee1,4));
       let fee2 = Number(ethers.utils.formatUnits(data.platformFee2,4));
       let fee3 = Number(ethers.utils.formatUnits(data.platformFee3,4));
       price = fee1 + fee2 + fee3

    } catch (err) {
    } finally {
      return price;
    }
  },
  async quoteExactInputSingle( tokenIn, tokenOut, fee, amountIn, priceLimit = 0, decimal) {
    const Contract = new ethers.Contract(qutorAbi.Contract, qutorAbi.contractAbi,  provider );
    
    let value = 0;
    try {
      let a = await Contract.callStatic.quoteExactInputSingle(
        tokenIn,
        tokenOut,
        fee,
        amountIn,
        priceLimit
      );
      value = ethers.utils.formatUnits(a, decimal);
      return value;
    } catch (error) {
      return value;
    }
  },
  async getTotal(res) {
    try {
      return {
        // 借入次数
        buyTime: ethers.utils.formatUnits(res.buyTime, 0),
        // 借出次数
        sellTime: ethers.utils.formatUnits(res.sellTime, 0),
        // 产生usdt数量
        usdt: parseFloat(ethers.utils.formatUnits(res.usdt, usdtContract[3])),
        // 交易btc数量
        vds: parseFloat(Number(ethers.utils.formatUnits(res.vds, btcContract[3])).toFixed(4)),
        vdsTip: parseFloat(ethers.utils.formatUnits(res.vdsTip, btcContract[3])),
               // 产生小费
        usdtTip: parseFloat(ethers.utils.formatUnits(res.usdtTip, usdtContract[3])),
          // 产生手续费
        vdsFee: parseFloat(ethers.utils.formatUnits(res.vdsFee, btcContract[3])),
        // usdt手续费
        usdtFee:parseFloat(ethers.utils.formatUnits(res.usdtFee, usdtContract[3])),
      };
    } catch (err) {
      return {};
    }
  },
  async total() {
    let obj = {}
    try {
      // btc价格
      let data  = await userEth.Contract.c2cTotal()
      obj = await this.getTotal(data)
    } catch (err) {
    } finally {
      store.commit("changeC2CTotal",obj)
      return obj
    }
  },
  async userTotal(account) {
    let obj = {}
    try {
      // btc价格
      let data  = await userEth.Contract.userTotal(account)
      obj = await this.getTotal(data)
    } catch (err) {
    } finally {
      if(account==store.state.address){
       store.commit("changeMyTotal",obj)
      }
      return obj
    }
  },
  async tarderTotal(account) {
    let obj = {}
    try {
      let data  = await userEth.Contract.tarderTotal(account)
      obj = await this.getTotal(data)
    } catch (err) {
    } finally {
      if(account==store.state.address){
       store.commit("changeMyTotal",obj)
      }
      return obj
    }
  },
  async getLatest(account) {
    let obj = {
      lastestPrice:0,
      orderType:1,
    }
    try {
      let id  = await ContractWithSinger.recordCount()
      let data =  await ContractWithSinger.getRecordById(Number(ethers.utils.formatUnits(id,0))  - 1)
      obj = {
        lastestPrice:  ethers.utils.formatUnits(data.price,usdtContract[3]) ,
        orderType:ethers.utils.formatUnits(data.orderType,0),
      }
      // obj = {
      //   lastestPrice:  ethers.utils.formatUnits(data.lastestPrice,usdtContract[3]) ,
      //   orderType:ethers.utils.formatUnits(data.orderType,0),
      // }
    } catch (err) {
    } finally {
       store.commit("changeLatestRecord",obj)
      return obj
    }
  },
  

  async getTraderItem(account) {
    await orderDB.initDB();
    // 获取交易员信息 先要获取本地 没有本地再查询
    let res = null
    try {
      res = await orderDB.getDataByKey("shopList", account);
    } catch (error) {
    }
    if (res && res[0] && res[0].account) {
      return res[0]
    }else{
      return  await userEth.getTraderDetail(account)
    }
  },  
  // 获取用户所有订单
  async getUserOrdersDetails(account) {
    let myAccount = await eth.getAccount();
    await orderDB.initDB();
    let params = {
      page: 0,
      pageSize:pageSize
    };
    const onload = async () => {
      try {
        let data = await ContractWithSinger.getUserOrders(account||myAccount,params.page,params.pageSize);
        let allPromise = [];
        data.forEach((e) => {
          if(e.createTime){
            allPromise.push(this.getOrder(e));
          }
        });
        let allData = await Promise.all(allPromise);
        await allData.forEach(async (obj, index) => {
          let res = await orderDB.getDataByKey("c2cOrderList", obj.id);
          let allobj = obj;
          if (res && res[0] && res[0].id) {
            allobj = Object.assign(res[0], obj);
          }
          await orderDB.updateData("c2cOrderList", allobj);
        });
        if (data.length == pageSize) {
          params.page++;
          await onload();
        } else {

        }
      } catch (err) {
      } finally {
      }
    };
    await onload();
  },
    // 获取用户所有交易记录
    async getUserRecord(account) {
      let myAccount = await eth.getAccount();
      await orderDB.initDB();
      let params = {
        page: 1,
        pageSize:pageSize
      };
      const onload = async () => {
        try {
          let data = await ContractWithSinger.getUserRecord(account||myAccount,params.page,params.pageSize);
          let allPromise = [];
          data.forEach((e) => {
            if(e.getTime){
              allPromise.push(this.getRecordOrder(e));
            }
          });
          let allData = await Promise.all(allPromise);
          await allData.forEach(async (obj, index) => {
            let res = await orderDB.getDataByKey("recordList", obj.id);
            let allobj = obj;
            if (res && res[0] && res[0].id) {
              allobj = Object.assign(res[0], obj);
            }
            await orderDB.updateData("recordList", allobj);
          });
          if (data.length == pageSize) {
            params.page++;
            await onload();
          } else {
  
          }
        } catch (err) {
        } finally {
        }
      };
      await onload();
    },

  
    // 获取用户所有订单
    async getUserPendingOrders(account) {
      let myAccount = await eth.getAccount();
      await orderDB.initDB();
      let params = {
        page: 1,
        pageSize:pageSize
      };
      const onload = async () => {
        try {
          let data = await ContractWithSinger.getUserPendingOrders(account||myAccount,params.page,params.pageSize);
          let allPromise = [];
          data.forEach((e) => {
            if(e.createTime){
              allPromise.push(this.getOrder(e));
            }
          });
          let allData = await Promise.all(allPromise);
          allData.forEach(async (obj, index) => {
            let res = await orderDB.getDataByKey("orderList", obj.id);
            let allobj = obj;
            if (res && res[0] && res[0].id) {
              allobj = Object.assign(res[0], obj);
            }
            await orderDB.updateData("orderList", allobj);
          });
          if (data.length == pageSize) {
            params.page++;
            await onload();
          } else {
  
          }
        } catch (err) {
        } finally {
        }
      };
      await onload();
    },
  
  // 查询全部挂单
  async getPendingLoanOrders(first) {
    await orderDB.initDB();
    let params = {
      page: 1,
      pageSize:pageSize
    };
    let allArr = []
    const onload = async () => {
      let arr = [];
      try {
        let data = await ContractWithSinger.getPendingLoanOrders(
          params.page,
          params.pageSize
        );
        let allPromise = [];
        data.forEach((e) => {
          allPromise.push(this.getOrder(e));
        });
        let allData = await Promise.all(allPromise);
        allData.forEach(async (obj, index) => {
          if(obj){
            arr.unshift(obj)
            let res = await orderDB.getDataByKey("c2cOrderList", obj.id);
            let allobj = obj;
            if (res && res[0] && res[0].id) {
              allobj = Object.assign(res[0], obj);
            }
            await orderDB.updateData("c2cOrderList", allobj);
          }
        });
        allArr = [...allArr, ...arr];
        store.commit("changeOrderList2", [...allArr]);
        if (first) {
          localStorage.setItem("orderFirstList2", JSON.stringify(allArr));
        }
        if (data.length == pageSize) {
          params.page ++
          await onload();
        } else {
        }
      } catch (err) {
      } finally {
      }
    };
    await onload();
  },
  // 分页查询交易员挂单
  async getTraderPendingOrders(account) {
    await orderDB.initDB();
    let params = {
      page: 1,
      pageSize:pageSize
    };
    let myAccount = await eth.getAccount();
    let realAccount = account || myAccount
    const onload = async () => {
      try {
        let data = await ContractWithSinger.getTraderPendingOrders
        (
          realAccount,
          params.page,
          params.pageSize
        );
        let allPromise = [];
        data.forEach((e) => {
          allPromise.push(this.getOrder(e));
        });
        let allData = await Promise.all(allPromise);
        allData.forEach(async (obj, index) => {
          if(obj){

          let res = await orderDB.getDataByKey("orderList", obj.id);
          let allobj = obj;
          if (res && res[0] && res[0].id) {
            allobj = Object.assign(res[0], obj);
          }
          await orderDB.updateData("orderList", allobj);
        }

        });
        if (data.length == pageSize) {
          params.page ++
          await onload();
        } else {
        }
      } catch (err) {
      } finally {
      }
    };
    await onload();
  },
  async getOrderDetail(id) {
    let obj = {};
    try {
      await orderDB.initDB();
      obj = await orderDB.getDataByKey("c2cOrderList", id);
      if (obj && obj.length > 0) {
        return obj[0];
      }
    } catch (error) {
    }
    obj = await this.orderList(id);
    return obj;
  },
  
  async getRecordOrder(res) {
    try {
      let myOwner = res.owner.toLowerCase()
      let type = ethers.utils.formatUnits(res.orderType, 0)
      if((res.owner.toLowerCase()==store.state.address)){
        if(type==2){
            myOwner = store.state.address
            type = '1'
        }else{
            myOwner = store.state.address
            type = '2'
        }
      }
      if(res.sender.toLowerCase()==store.state.address){
         myOwner = store.state.address
      }
      let orderType = ethers.utils.formatUnits(res.orderType, 0)
      return {
        id: Number(ethers.utils.formatUnits(res.id, 0)),
        orderId:Number(ethers.utils.formatUnits(res.orderId, 0)),
        amount: parseFloat(ethers.utils.formatUnits(res.amount, orderType==1?  btcContract[3] :usdtContract[3]  )),
        getAmount:parseFloat(ethers.utils.formatUnits(res.getAmount, orderType==1? usdtContract[3] : btcContract[3] )),
        price:parseFloat(ethers.utils.formatUnits(res.price, usdtContract[3])),
        getTime:   getDate(res.getTime * 1000),
        orderType,
        type:type,
        myOwner,
        owner: res.owner.toLowerCase(),
        sender:res.sender.toLowerCase(),
        remark:res.remark,
      };
    } catch (err) {
      return null;
    }
  },
async getOrder(res) {
    try {
      let platForm = {
        name:"",
        url:"",
      }
      if(res.tarder&&res.tarder!=store.state.address0){
        // 获取交易员
        platForm = await  this.getTraderItem(res.tarder.toLowerCase())
      }
      let orderType = ethers.utils.formatUnits(res.orderType, 0)
      return {
        id: Number(ethers.utils.formatUnits(res.id, 0)),
        amount: parseFloat(ethers.utils.formatUnits(res.amount, orderType==1? btcContract[3] : usdtContract[3])),
        allAmount:parseFloat(ethers.utils.formatUnits(res.allAmount, orderType==1? btcContract[3] : usdtContract[3])),
        price:parseFloat(ethers.utils.formatUnits(res.price, usdtContract[3])),
        priceType:ethers.utils.formatUnits(res.priceType, 0),
        rateType:ethers.utils.formatUnits(res.rateType, 0),
        upRate:ethers.utils.formatUnits(res.upRate, 4),
        createTime: getDate(res.createTime * 1000),
        duration: ethers.utils.formatUnits(res.duration, 0),
        updateTime:   getDate(res.updateTime * 1000),
        orderType,
        tip:ethers.utils.formatUnits(res.tip, 4),
        status: ethers.utils.formatUnits(res.status, 0),
        owner: res.owner.toLowerCase(),
        tarder: res.tarder.toLowerCase(),
        describe:platForm.describe,
        name:platForm.name,
        url:platForm.url,
        remark:res.remark,
      };
    } catch (err) {
      return null;
    }
  },
  // 单独获取一个订单详情
  async orderList(id) {
    let obj = {};
    try {
      let item = await Contract.getOrderById(id);
      obj = this.getOrder(item);
    } catch (err) {
    } finally {
      return obj;
    }
  },
};
export default c2cEth;
